/*
 * EU4RIAClassLoader.java July 2009
 *
 * Copyright (C) 2009, Quirino Zagarese <quirino@laszloitalia.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA  02111-1307  USA
 */
package org.eu4ria.core;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class EU4RIAClassLoader extends URLClassLoader {


	private static EU4RIAClassLoader instance = null;

	private Hashtable<String, byte[]> classDataTable = new Hashtable<String, byte[]>();

	public EU4RIAClassLoader(URL[] urls) {
		super(urls);
	}

	protected Class<?> findClass(String name){
		byte[] data = classDataTable.get(name);
		return (data != null)? defineClass(name, data, 0, data.length) : null;
	}

	public void addUrl(URL url){
		super.addURL(url);
	}

	public void importArchive(File jar) {
		JarFile jarFile = null;
		try {
			jarFile = new JarFile(jar);
		} catch (IOException e) {
			e.printStackTrace();
		}
		Enumeration<JarEntry> entries = jarFile.entries();
		while (entries.hasMoreElements()) {
			JarEntry entry = entries.nextElement();
			String name = entry.getName();
			if (name.endsWith(".class")) {
				name = name.substring(0, name.indexOf(".class"));
				name = name.replaceAll(File.separator, ".");
				byte buf[];
				try {
					InputStream stream = jarFile.getInputStream(entry);
					buf = getClassBytes(stream);
					classDataTable.put(name, buf);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	private byte[] getClassBytes(InputStream is) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		BufferedInputStream bis = new BufferedInputStream(is);
		boolean eof = false;
		while (!eof) {
			try {
				int i = bis.read();
				if (i == -1)
					eof = true;
				else baos.write(i);
			} catch (IOException e) {
				return null;
			}
		}
		return baos.toByteArray();
	}

	public static EU4RIAClassLoader getInstance() {
		if(instance == null){
			instance = new EU4RIAClassLoader(new URL[0]);
		}
		return instance;
	}

}
